/**
 *******************************************************************************
 * @file  rtc_calendar.c
 * @brief 
 @verbatim
   Change Logs:
   Date             Author          Notes
   2022-10-11       lyd            1.1
 @endverbatim

 *******************************************************************************
 */
 

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>

#include "iot_node.h"
#include "iotv30_config.h"
#include "proto_plat.h"
#include "uart_printf.h"
#include "user_flash.h"

//#include  "CCT_Logic_Lamp.h"
//#include  "CCT_Logic.h"



#include  "rtc_calendar.h"


uint32_t u32RunTime_Sec = 0;
		
RTC_Data_st   RTC_Now; 

uint8_t u8SecIntFlag = 0 ;


/**
 * @brief  RTC display weekday.
 * @param  [in] u8Weekday               Weekday
 *         This parameter can be one of the following values:
 *           @arg RTC_WEEKDAY_SUNDAY:     Sunday
 *           @arg RTC_WEEKDAY_MONDAY:     Monday
 *           @arg RTC_WEEKDAY_TUESDAY:    Tuesday
 *           @arg RTC_WEEKDAY_WEDNESDAY:  Wednesday
 *           @arg RTC_WEEKDAY_THURSDAY:   Thursday
 *           @arg RTC_WEEKDAY_FRIDAY:     Friday
 *           @arg RTC_WEEKDAY_SATURDAY:   Saturday
 * @retval None
 */
static void RTC_DisplayWeekday(uint8_t u8Weekday)
{
    switch (u8Weekday)
    {
        case RTC_WEEKDAY_SUNDAY:
            (void)printf("Sunday\r\n");
            break;
        case RTC_WEEKDAY_MONDAY:
            (void)printf("Monday\r\n");
            break;
        case RTC_WEEKDAY_TUESDAY:
            (void)printf("Tuesday\r\n");
            break;
        case RTC_WEEKDAY_WEDNESDAY:
            (void)printf("Wednesday\r\n");
            break;
        case RTC_WEEKDAY_THURSDAY:
            (void)printf("Thursday\r\n");
            break;
        case RTC_WEEKDAY_FRIDAY:
            (void)printf("Friday\r\n");
            break;
        case RTC_WEEKDAY_SATURDAY:
            (void)printf("Saturday\r\n");
            break;
        default:
            break;
    }
}







 //extern  RTC_Data_st   RTC_Now; 

/** 2021-12-10 星期五 16:48:00 
 * @brief  配置 RTC calendar configuration.
 * @param  None
 * @retval None
 */
void RTC_Write(RTC_Data_st*   rtc_new )
{
char rtc_str[32];

memset(rtc_str,0,sizeof(rtc_str) );  

sprintf(rtc_str, "date -s \"%04d-%02d-%02d %02d:%02d:%02d\"", 2000+rtc_new->ucYear, rtc_new->ucMonth, rtc_new->ucDate, rtc_new->ucHour, rtc_new->ucMinute, rtc_new->ucSecond);//debug ---3.7

//	sprintf(pdst, "%[04d-%02d-%02dT%02d:%02d:%02d.%03d+0800]", year, month, day, hour, min, sec, usec/1000);
	
// date -s "2023-09-13 11:59:00"   
// date -s "2023-09-13 12:01:00" 

  system(rtc_str);
 // system("hwclock -s");          //--hctosys 	# 以硬件时钟为准，校正系统时钟 
  system("hwclock -w");   //--systohc 	# 以系统时钟为准，校正硬件时钟



#if   DEBUG_PRINT_ENABLE

    printf("设置当前时间\r\n");
    logout("%s", rtc_str);

#endif




}




// ubuntu@vmhost:~/t0/prj/timer$ date
// 2023年 09月 23日 星期六 23:43:10 CST
// ubuntu@vmhost:~/t0/prj/timer$ date +"%F %T"
// 2023-09-23 23:43:39
// ubuntu@vmhost:~/t0/prj/timer$ 


// #include <stdio.h>
// #include <time.h>
 
int main_exam(void) {

  time_t current_time = time(NULL);  // 获取当前的 Unix 时间戳

   printf("%s\n",ctime(&current_time)); //Sat Sep 23 23:34:45 2023
   printf("%s\n",asctime(gmtime(&current_time))); //Sat Sep 23 15:34:45 2023------格林尼治时间

  struct tm *local_time = localtime(&current_time);  // 将时间戳转换为本地时间

  printf("当前时间：%d年%d月%d日 %d:%d:%d 周%d\n", 
    local_time->tm_year + 1900, local_time->tm_mon + 1, local_time->tm_mday, 
    local_time->tm_hour, local_time->tm_min, local_time->tm_sec,local_time->tm_wday);
//前时间：2023年9月23日 23:34:45
//当前时间：2023年9月23日 23:39:8 周6

  return 0;
}



//对于需要在程序中获取时间戳的情况，Linux提供了C语言的编程接口。以下是两个常用的函数：
//	time()函数：这个函数返回从1970年1月1日至今的秒数，即当前的时间戳。
//它的使用非常简单，只需要包含<time.h>头文件并调用time(NULL)即可获取当前时间戳。
// #include <time.h>
// #include <stdio.h>
/**
 * @brief 获取系统时间（秒）
 *
 * @return 时间戳（单位：秒）
 *  
 * @details UTC时间
 */
 //uint64_t cm_rtc_get_current_time(void);
uint64_t RTC_get_timestamp(void) 
{
  time_t timestamp_now;
  timestamp_now = time(NULL);
  printf("当前时间戳：%ld秒\n", timestamp_now);
  return timestamp_now;
}





/**
 * @brief 设置系统时间（秒）
 * 
 * @param [in] timestamp_new 时间戳(单位：秒)
  *
 * @return 
 *   = 0  - 成功 \n
 *   < 0  - 失败, 返回值为错误码
 *  
 * @details UTC时间
 */
 //int32_t cm_rtc_set_current_time(uint64_t second);
int32_t RTC_set_timestamp(uint64_t timestamp_new)
{
 RTC_Data_st  rtc_new ; 

 //time_t cur_timestamp   = time(NULL);  // 获取当前的 Unix 时间戳
 time_t cur_timestamp   = timestamp_new;  // 获取当前的 Unix 时间戳

 struct tm *local_time = localtime(&cur_timestamp);  // 将时间戳转换为本地时间

//rtc_new.ucYear = (local_time->tm_year + 1900)-2000;
  rtc_new.ucYear   = local_time->tm_year -100;
  rtc_new.ucMonth  = local_time->tm_mon + 1;
  rtc_new.ucDate   = local_time->tm_mday;
  rtc_new.ucHour   = local_time->tm_hour;
  rtc_new.ucMinute = local_time->tm_min;
  rtc_new.ucSecond = local_time->tm_sec;
  rtc_new.ucWeek   = local_time->tm_wday;

  RTC_Write( &rtc_new );

  return 0;
}


  static int8_t time_zone_now;


/**
 * @brief 设置时区
 * 
 * @param [in] timezone 时区
 *
 * @return 
 *   = 0  - 成功 \n
 *   < 0  - 失败, 返回值为错误码
 *
 * @details timezone设置范围为-12~12，-12为西十二区，0为世界时间，12为东十二区
 */
//int32_t cm_rtc_set_timezone(int32_t timezone);

int32_t  RTC_set_timezone(int8_t timezone)
{

#if 0
char rtc_str[32];

memset(rtc_str,0,sizeof(rtc_str) );  

sprintf(rtc_str, "date -s \"%04d-%02d-%02d %02d:%02d:%02d\"", 2000+rtc_new->ucYear, rtc_new->ucMonth, rtc_new->ucDate, rtc_new->ucHour, rtc_new->ucMinute, rtc_new->ucSecond);//debug ---3.7

//	sprintf(pdst, "%[04d-%02d-%02dT%02d:%02d:%02d.%03d+0800]", year, month, day, hour, min, sec, usec/1000);
	
// date -s "2023-09-13 11:59:00"   
// date -s "2023-09-13 12:01:00" 

  system(rtc_str);
 // system("hwclock -s");          //--hctosys 	# 以硬件时钟为准，校正系统时钟 
  system("hwclock -w");   //--systohc 	# 以系统时钟为准，校正硬件时钟


  time_t now;
  now = time(NULL);
//  printf("当前时间戳：%ld秒\n", now);
  return now;

#endif


time_zone_now =timezone;

  return 0;
}




/**
 * @brief 获取时区
 *
 * @return 时区
 *  
 * @details timezone范围为-12~12，-12为西十二区，0为世界时间，12为东十二区
 */
//int32_t cm_rtc_get_timezone(void);
int32_t  RTC_get_timezone( void )
{

time_zone_now =timezone;

  return 0;

#if 0

char rtc_str[32];

memset(rtc_str,0,sizeof(rtc_str) );  

sprintf(rtc_str, "date -s \"%04d-%02d-%02d %02d:%02d:%02d\"", 2000+rtc_new->ucYear, rtc_new->ucMonth, rtc_new->ucDate, rtc_new->ucHour, rtc_new->ucMinute, rtc_new->ucSecond);//debug ---3.7

//	sprintf(pdst, "%[04d-%02d-%02dT%02d:%02d:%02d.%03d+0800]", year, month, day, hour, min, sec, usec/1000);
	
// date -s "2023-09-13 11:59:00"   
// date -s "2023-09-13 12:01:00" 

  system(rtc_str);
 // system("hwclock -s");          //--hctosys 	# 以硬件时钟为准，校正系统时钟 
  system("hwclock -w");   //--systohc 	# 以系统时钟为准，校正硬件时钟

  return 8;

#endif

}









void RTC_Read(RTC_Data_st* rtc_new )
{

 time_t timestamp_now   = time(NULL);  // 获取当前的 Unix 时间戳

 struct tm *local_time = localtime(&timestamp_now);  // 将时间戳转换为本地时间

//rtc_new->ucYear = (local_time->tm_year + 1900)-2000;
  rtc_new->ucYear   = local_time->tm_year -100;
  rtc_new->ucMonth  = local_time->tm_mon + 1;
  rtc_new->ucDate   = local_time->tm_mday;
  rtc_new->ucHour   = local_time->tm_hour;
  rtc_new->ucMinute = local_time->tm_min;
  rtc_new->ucSecond = local_time->tm_sec;
  rtc_new->ucWeek   = local_time->tm_wday;



#if 0// DEBUG_PRINT_ENABLE

    printf("当前时间：%d年%d月%d日 %d:%d:%d 周%d\n", 
    local_time->tm_year + 1900, local_time->tm_mon + 1, local_time->tm_mday, 
    local_time->tm_hour, local_time->tm_min, local_time->tm_sec,local_time->tm_wday);

#endif



  // system("date");


	#if 0			
		rtc_new->ucYear   = stcRtcDate.u8Year ;
		rtc_new->ucMonth  = stcRtcDate.u8Month  ;	
		rtc_new->ucDate   = stcRtcDate.u8Day ;	    //日期
		rtc_new->ucWeek    = stcRtcDate.u8Weekday  ;	//星期
	
		rtc_new->ucHour   = stcRtcTime.u8Hour;
		rtc_new->ucMinute = stcRtcTime.u8Minute;
		rtc_new->ucSecond = stcRtcTime.u8Second;							
#endif
		
}





/**
 * @brief  Process function of RTC Calendar.
 * @param  None    ------周期 1sec---------
 * @retval None
 */
void RTC_Process(void)
{

static uint8_t rtc_min  = 0;
static uint8_t rtc_hour = 0;	

static uint8_t sec_cnt  = 0;
static uint8_t min_cnt  = 0;
	
	

        RTC_Read(&RTC_Now); // HC32_RTC_Read  


       //iot_Node_Test_tick_min( );   //测试阶段


				if( 0==sec_cnt )
				{
						sec_cnt  = TLV_PollPeriod_sec;//10; -2
			     iot_Node_Test_tick_min( );   //测试阶段
				}	else{
						sec_cnt--;
				}
						

		
		if( rtc_min != RTC_Now.ucMinute )
		{
		    rtc_min = RTC_Now.ucMinute;
				UserData.Reg.RunTimeMin++;		

				printf("RTC_Now:");
				RTC_Prinft( &RTC_Now );

#if 1 //!RELEASE_VER_ENABLE			
			
		    printf("TotallRunTimeMin=%d\r\n",UserData.Reg.RunTimeMin);
		    printf("RunningTime_Sec=%d\r\n",u32RunTime_Sec);								
			
#endif


			//////主动轮询节点的周期时间--这个需要小于等于-  TLV_ReportPeriod_sec   ( 2*60 )   -否则意义不大  
        // iot_Node_Test_tick_min( );   //时间发布结果---
         
				
				if( 0==min_cnt )
				{
					min_cnt  = 3;		

        //iot_Node_Test_tick_min( );   //时间发布结果


          //------ver.4.24-----20240306---------------------------------
  //         logout("SoftWare_Ver.%02d.%02d.%02d.%02d\r\n",CCT_SW_VerHex[0],CCT_SW_VerHex[1],CCT_SW_VerHex[2],CCT_SW_VerHex[3]  ); //软件版本号FW_Version
					// printf("SoftWare_Ver.,%02x,%02x,%02x,%02x\r\n",CCT_SW_VerHex[0],CCT_SW_VerHex[1],CCT_SW_VerHex[2],CCT_SW_VerHex[3]  );																				
					
				}	else{
						min_cnt--;
				}
									
				
		}


		if( rtc_hour != RTC_Now.ucHour )
		{
		    rtc_hour = RTC_Now.ucHour;
				//UserData_SaveEnable( );			
		}
				

}







/**
 * @brief  Process function of RTC Calendar.
 * @param  None
 * @retval None
 */
void RTC_Prinft(RTC_Data_st* rtc )
{

		/* Print current date and time */
		(void)printf("20%02d/%02d/%02d %02d:%02d:%02d -%d", rtc->ucYear, rtc->ucMonth,
		               rtc->ucDate, rtc->ucHour,
					   rtc->ucMinute, rtc->ucSecond, rtc->ucWeek);
		RTC_DisplayWeekday(rtc->ucWeek);
			

}



/**
 * @brief  Process function of RTC Calendar.
 * @param  None
 * @retval None
 */
void RTC_Prinft_Now(void )
{

    RTC_Read(&RTC_Now); // HC32_RTC_Read  

		/* Print current date and time */
		(void)printf("%02d:%02d:%02d-", RTC_Now.ucHour, RTC_Now.ucMinute, RTC_Now.ucSecond);


		/* Print current date and time */
		// (void)printf("20%02d/%02d/%02d %02d:%02d:%02d -%d", RTC_Now.ucYear, RTC_Now.ucMonth,
		//                RTC_Now.ucDate, RTC_Now.ucHour,
		// 			   RTC_Now.ucMinute, RTC_Now.ucSecond, RTC_Now.ucWeek);
		// RTC_DisplayWeekday(RTC_Now.ucWeek);
			

}

